#include "qlib_python.h"

PYBIND11_MODULE(ql_qlibpy, m) {
  // Get
  {
    py::class_<Get> pybind_sing(m, "Obj");
    pybind_sing.def(py::init<>());
    // pybind_sing.def_readwrite_static("librarys", &Get::librarys);
    // pybind_sing.def_static("set_library", &Get::set_library);
  }

  // DB
  {
    // py::class_<DB> pybind_DB(m, "DB");
    // pybind_DB.def_static("read_gds", &DB::read_gds, py::return_value_policy::reference);
    // pybind_DB.def_static("write_gds", py::overload_cast<const Library::s_ptr, std::string, uint64_t, tm*>(DB::write_gds));
    // pybind_DB.def_static("read_oas", &DB::read_oas);
    // pybind_DB.def_static("write_osa", &DB::write_oas);
    // pybind_DB.def_static("write_svg", py::overload_cast<const Cell::s_ptr, std::string, double, uint32_t, std::string, double, bool>(&DB::write_svg));
  }

  // // Library
  // {
  //   py::class_<Library, std::shared_ptr<Library>> py_Library(m, "Library");

  //   py_Library.def(py::init<>());
  //   py_Library.def_static("create", py::overload_cast<>(&Library::create), py::return_value_policy::reference);

  //   DEF_STATS(Library, name);
  //   DEF_STATS(Library, unit);
  //   DEF_STATS(Library, precision);
  //   DEF_STATS(Library, cells);
  //   DEF_STATS(Library, properties);

  //   DEF_METHOD(Library, copy);
  //   DEF_METHOD(Library, add);
  //   DEF_METHOD(Library, remove);
  //   DEF_METHOD(Library, new_cell);
  //   DEF_METHOD(Library, remap);
  //   DEF_METHOD(Library, rename_cell);
  //   DEF_METHOD(Library, replace_cell);
  //   DEF_METHOD(Library, get_layers);
  //   DEF_METHOD(Library, update_cells_map);

  //   py::bind_vector<LibraryPtrArray>(m, "LibraryPtrArray");
  //   m.def("LibraryArray_Size", &vector_size<Library::s_ptr>);
  //   m.def("LibraryArray_Resize", &vector_resize<Library::s_ptr>);
  // }

  // // Cell
  // {
  //   py::class_<Cell, std::shared_ptr<Cell>> py_Cell(m, "Cell");

  //   py_Cell.def(py::init<>());
  //   py_Cell.def_static("create", py::overload_cast<>(&Cell::create));

  //   DEF_STATS(Cell, name);
  //   DEF_STATS(Cell, path_map);
  //   DEF_STATS(Cell, label_map);
  //   DEF_STATS(Cell, text_map);
  //   DEF_STATS(Cell, polygon_map);
  //   DEF_STATS(Cell, rectangle_map);
  //   DEF_STATS(Cell, circle_map);
  //   DEF_STATS(Cell, reference_map);
  //   DEF_STATS(Cell, properties);
  //   DEF_STATS(Cell, reference_number);

  //   DEF_METHOD(Cell, copy);
  //   py_Cell.def("add", py::overload_cast<Path::s_ptr>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<Label::s_ptr>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<Polygon::s_ptr>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<Text::s_ptr>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<Reference::s_ptr>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<Rectangle::s_ptr>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<Circle::s_ptr>(&Cell::add));

  //   py_Cell.def("add", py::overload_cast<PathPtrArray&>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<LabelPtrArray&>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<PolygonPtrArray&>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<ReferencePtrArray&>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<RectanglePtrArray&>(&Cell::add));
  //   py_Cell.def("add", py::overload_cast<CirclePtrArray&>(&Cell::add));

  //   py_Cell.def("remove", py::overload_cast<Path::s_ptr>(&Cell::remove));
  //   py_Cell.def("remove", py::overload_cast<Label::s_ptr>(&Cell::remove));
  //   py_Cell.def("remove", py::overload_cast<Polygon::s_ptr>(&Cell::remove));
  //   py_Cell.def("remove", py::overload_cast<Reference::s_ptr>(&Cell::remove));
  //   py_Cell.def("remove", py::overload_cast<Rectangle::s_ptr>(&Cell::remove));
  //   py_Cell.def("remove", py::overload_cast<Circle::s_ptr>(&Cell::remove));

  //   py_Cell.def("bounding_box", py::overload_cast<>(&Cell::bounding_box, py::const_));
  //   py_Cell.def("convex_hull", py::overload_cast<Vec2dArray&>(&Cell::convex_hull, py::const_));
  //   py_Cell.def("get_layers", py::overload_cast<>(&Cell::get_layers));

  //   DEF_METHOD(Cell, dependencies);
  //   DEF_METHOD(Cell, get_labels);
  //   DEF_METHOD(Cell, get_flexpaths);
  //   DEF_METHOD(Cell, get_polygons);
  //   DEF_METHOD(Cell, remap);

  //   py::bind_vector<CellPtrArray>(m, "CellPtrArray");
  //   m.def("CellArray_Size", &vector_size<Cell::s_ptr>);
  //   m.def("CellArray_Resize", &vector_resize<Cell::s_ptr>);
  // }

  // // Reference
  // {
  //   py::class_<Reference, std::shared_ptr<Reference>> py_Reference(m, "Reference");

  //   py_Reference.def(py::init<>());
  //   py_Reference.def_static("create", py::overload_cast<>(&Reference::create));
  //   DEF_METHOD(Reference, copy);

  //   DEF_STATS(Reference, type);
  //   DEF_STATS(Reference, cell);
  //   DEF_STATS(Reference, origin);
  //   DEF_STATS(Reference, rotation);
  //   DEF_STATS(Reference, magnification);
  //   DEF_STATS(Reference, x_reflection);
  //   DEF_STATS(Reference, properties);
  //   DEF_STATS(Reference, repetition);

  //   DEF_METHOD(Reference, apply_repetition);
  //   DEF_METHOD(Reference, get_labels);
  //   DEF_METHOD(Reference, get_polygons);
  //   DEF_METHOD(Reference, get_flexpaths);
  //   DEF_METHOD(Reference, repeat_and_transform);

  //   py_Reference.def("bounding_box", py::overload_cast<Vec2d&, Vec2d&>(&Reference::bounding_box, py::const_));
  //   py_Reference.def("convex_hull", py::overload_cast<Vec2dArray&>(&Reference::convex_hull, py::const_));
  // }

  // // Polygon
  // {
  //   py::class_<Polygon, std::shared_ptr<Polygon>> py_Polygon(m, "Polygon");

  //   py_Polygon.def(py::init<>());
  //   py_Polygon.def_static("create", py::overload_cast<>(&Polygon::create));
  //   DEF_METHOD(Polygon, copy);

  //   DEF_STATS(Polygon, layer);
  //   DEF_STATS(Polygon, datatype);
  //   DEF_STATS(Polygon, points);
  //   DEF_STATS(Polygon, properties);
  //   DEF_STATS(Polygon, repetition);

  //   DEF_METHOD(Polygon, apply_repetition);
  //   DEF_METHOD(Polygon, area);
  //   DEF_METHOD(Polygon, signed_area);
  //   DEF_METHOD(Polygon, bounding_box);
  //   DEF_METHOD(Polygon, contain_all);
  //   DEF_METHOD(Polygon, contain_any);
  //   DEF_METHOD(Polygon, fillet);
  //   DEF_METHOD(Polygon, fracture);
  //   DEF_METHOD(Polygon, mirror);
  //   DEF_METHOD(Polygon, perimeter);
  //   DEF_METHOD(Polygon, scale);
  //   DEF_METHOD(Polygon, rotate);
  //   DEF_METHOD(Polygon, translate);
  //   DEF_METHOD(Polygon, transform);

  //   py_Polygon.def("contain", py::overload_cast<const Vec2d&>(&Polygon::contain, py::const_));
  //   py_Polygon.def("contain", py::overload_cast<const Vec2dArray&, std::vector<bool>&>(&Polygon::contain, py::const_));
  // }

  // // Label
  // {
  //   py::class_<Label, std::shared_ptr<Label>> py_Label(m, "Label");

  //   py_Label.def(py::init<>());
  //   py_Label.def_static("create", py::overload_cast<>(&Label::create));
  //   DEF_METHOD(Label, copy);

  //   DEF_STATS(Label, layer);
  //   DEF_STATS(Label, text);
  //   DEF_STATS(Label, origin);
  //   DEF_STATS(Label, anchor);
  //   DEF_STATS(Label, rotation);
  //   DEF_STATS(Label, magnification);
  //   DEF_STATS(Label, x_reflection);
  //   DEF_STATS(Label, properties);
  //   DEF_STATS(Label, repetition);

  //   DEF_METHOD(Label, apply_repetition);
  //   DEF_METHOD(Label, bounding_box);
  //   DEF_METHOD(Label, transform);
  // }

  // // Path
  // {
  //   py::class_<Path, std::shared_ptr<Path>> py_Path(m, "Path");

  //   py_Path.def(py::init<>());
  //   py_Path.def_static("create", py::overload_cast<>(&Path::create));
  //   DEF_METHOD(Path, copy);

  //   DEF_STATS(Path, type);
  //   DEF_STATS(Path, spine);
  //   DEF_STATS(Path, layer);
  //   DEF_STATS(Path, datatype);
  //   DEF_STATS(Path, elements);
  //   DEF_STATS(Path, simple_path);
  //   DEF_STATS(Path, scale_width);
  //   DEF_STATS(Path, m_raith_data);
  //   DEF_STATS(Path, properties);
  //   DEF_STATS(Path, repetition);

  //   DEF_METHOD(Path, init_spine);
  //   DEF_METHOD(Path, init_waveguide);
  //   DEF_METHOD(Path, apply_repetition);
  //   DEF_METHOD(Path, arc);
  //   DEF_METHOD(Path, bezier);
  //   DEF_METHOD(Path, commands);
  //   DEF_METHOD(Path, cubic);
  //   DEF_METHOD(Path, cubic_smooth);
  //   DEF_METHOD(Path, interpolation);
  //   DEF_METHOD(Path, mirror);
  //   DEF_METHOD(Path, parametric);
  //   DEF_METHOD(Path, path_spines);
  //   DEF_METHOD(Path, quadratic);
  //   DEF_METHOD(Path, rotate);
  //   DEF_METHOD(Path, scale);
  //   DEF_METHOD(Path, to_polygons);
  //   DEF_METHOD(Path, translate);
  //   DEF_METHOD(Path, turn);
  //   DEF_METHOD(Path, widths);
  //   DEF_METHOD(Path, fill_offsets_and_widths);
  //   DEF_METHOD(Path, remove_overlapping_points);
  //   DEF_METHOD(Path, element_center);

  //   py_Path.def("init", py::overload_cast<const Vec2d, double, double, double, uint32_t, uint32_t>(&Path::init));
  //   py_Path.def("init", py::overload_cast<const Vec2d, const double*, const double*, double, uint32_t, uint32_t>(&Path::init));
  // }

  // // Circle
  // {
  //   py::class_<Circle, std::shared_ptr<Circle>> py_Circle(m, "Circle");

  //   py_Circle.def(py::init<>());
  //   py_Circle.def_static("create", py::overload_cast<>(&Circle::create));
  //   DEF_METHOD(Circle, copy);

  //   DEF_STATS(Circle, center);
  //   DEF_STATS(Circle, radius);
  //   DEF_STATS(Circle, tolerance);
  //   DEF_STATS(Circle, layer);
  //   DEF_STATS(Circle, datatype);
  //   DEF_STATS(Circle, properties);
  //   DEF_STATS(Circle, repetition);

  //   DEF_METHOD(Circle, init);
  //   DEF_METHOD(Circle, to_polygon);
  //   DEF_METHOD(Circle, scale);
  //   DEF_METHOD(Circle, mirror);
  //   DEF_METHOD(Circle, translate);
  //   DEF_METHOD(Circle, transform);
  // }

  // // Ellipse
  // {
  //   py::class_<Ellipse, std::shared_ptr<Ellipse>> py_Ellipse(m, "Ellipse");

  //   py_Ellipse.def(py::init<>());
  //   py_Ellipse.def_static("create", py::overload_cast<>(&Ellipse::create));
  //   DEF_METHOD(Ellipse, copy);

  //   DEF_STATS(Ellipse, center);
  //   DEF_STATS(Ellipse, radius);
  //   DEF_STATS(Ellipse, tolerance);
  //   DEF_STATS(Ellipse, layer);
  //   DEF_STATS(Ellipse, datatype);
  //   DEF_STATS(Ellipse, properties);
  //   DEF_STATS(Ellipse, rotation);
  //   DEF_STATS(Ellipse, repetition);

  //   DEF_METHOD(Ellipse, init);
  //   DEF_METHOD(Ellipse, to_polygon);
  //   DEF_METHOD(Ellipse, scale);
  //   DEF_METHOD(Ellipse, mirror);
  //   DEF_METHOD(Ellipse, translate);
  //   DEF_METHOD(Ellipse, transform);
  // }

  // // Fan
  // {
  //   py::class_<Fan, std::shared_ptr<Fan>> py_Fan(m, "Fan");

  //   py_Fan.def(py::init<>());
  //   py_Fan.def_static("create", py::overload_cast<>(&Fan::create));
  //   DEF_METHOD(Fan, copy);

  //   DEF_STATS(Fan, center);
  //   DEF_STATS(Fan, radius);
  //   DEF_STATS(Fan, angle);
  //   DEF_STATS(Fan, tolerance);
  //   DEF_STATS(Fan, layer);
  //   DEF_STATS(Fan, datatype);
  //   DEF_STATS(Fan, properties);
  //   DEF_STATS(Fan, rotation);
  //   DEF_STATS(Fan, repetition);

  //   DEF_METHOD(Fan, init);
  //   DEF_METHOD(Fan, to_polygon);
  //   DEF_METHOD(Fan, scale);
  //   DEF_METHOD(Fan, mirror);
  //   DEF_METHOD(Fan, translate);
  //   DEF_METHOD(Fan, transform);
  // }

  // // FlexEllipse
  // {
  //   py::class_<FlexEllipse, std::shared_ptr<FlexEllipse>> py_FlexEllipse(m, "FlexEllipse");

  //   py_FlexEllipse.def(py::init<>());
  //   py_FlexEllipse.def_static("create", py::overload_cast<>(&FlexEllipse::create));
  //   DEF_METHOD(FlexEllipse, copy);

  //   DEF_STATS(FlexEllipse, center);
  //   DEF_STATS(FlexEllipse, radius);
  //   DEF_STATS(FlexEllipse, inner_radius);
  //   DEF_STATS(FlexEllipse, angle);
  //   DEF_STATS(FlexEllipse, tolerance);
  //   DEF_STATS(FlexEllipse, layer);
  //   DEF_STATS(FlexEllipse, datatype);
  //   DEF_STATS(FlexEllipse, properties);
  //   DEF_STATS(FlexEllipse, rotation);
  //   DEF_STATS(FlexEllipse, repetition);

  //   DEF_METHOD(FlexEllipse, init);
  //   DEF_METHOD(FlexEllipse, to_polygon);
  //   DEF_METHOD(FlexEllipse, scale);
  //   DEF_METHOD(FlexEllipse, mirror);
  //   DEF_METHOD(FlexEllipse, translate);
  //   DEF_METHOD(FlexEllipse, transform);
  // }

  // // Rectangle
  // {
  //   py::class_<Rectangle, std::shared_ptr<Rectangle>> py_Rectangle(m, "Rectangle");

  //   py_Rectangle.def(py::init<>());
  //   py_Rectangle.def_static("create", py::overload_cast<>(&Rectangle::create));
  //   DEF_METHOD(Rectangle, copy);

  //   DEF_STATS(Rectangle, layer);
  //   DEF_STATS(Rectangle, datatype);
  //   DEF_STATS(Rectangle, pos);
  //   DEF_STATS(Rectangle, width);
  //   DEF_STATS(Rectangle, height);
  //   DEF_STATS(Rectangle, properties);
  //   DEF_STATS(Rectangle, repetition);

  //   DEF_METHOD(Rectangle, to_polygon);

  //   py_Rectangle.def("init", py::overload_cast<const Vec2d&, double, double, uint32_t, uint32_t>(&Rectangle::init));
  //   py_Rectangle.def("init", py::overload_cast<const Vec2d&, const Vec2d&, uint32_t, uint32_t>(&Rectangle::init));
  // }

  // // Text
  // {
  //   py::class_<Text, std::shared_ptr<Text>> py_Text(m, "Text");

  //   py_Text.def(py::init<>());
  //   py_Text.def_static("create", py::overload_cast<>(&Text::create));
  //   DEF_METHOD(Text, copy);

  //   DEF_STATS(Text, text);
  //   DEF_STATS(Text, size);
  //   DEF_STATS(Text, vertical);
  //   DEF_STATS(Text, layer);
  //   DEF_STATS(Text, datatype);
  //   DEF_STATS(Text, properties);
  //   DEF_STATS(Text, repetition);

  //   DEF_METHOD(Text, init);
  // }

  // // Trapezoid
  // {
  //   py::class_<Trapezoid, std::shared_ptr<Trapezoid>> py_Trapezoid(m, "Trapezoid");

  //   py_Trapezoid.def(py::init<>());
  //   py_Trapezoid.def_static("create", py::overload_cast<>(&Trapezoid::create));
  //   DEF_METHOD(Trapezoid, copy);

  //   DEF_STATS(Trapezoid, layer);
  //   DEF_STATS(Trapezoid, datatype);
  //   DEF_STATS(Trapezoid, properties);
  //   DEF_STATS(Trapezoid, repetition);

  //   DEF_STATS(Trapezoid, position);
  //   DEF_STATS(Trapezoid, width);
  //   DEF_STATS(Trapezoid, height);

  //   py_Trapezoid.def("init", py::overload_cast<const Vec2d&, double, double, uint32_t, uint32_t>(&Trapezoid::init));
  //   py_Trapezoid.def("init", py::overload_cast<const Vec2d&, const Vec2d&, uint32_t, uint32_t>(&Trapezoid::init));
  // }

  // // Repetition
  // {
  //   py::enum_<RepetitionType> py_RepetitionType(m, "RepetitionType");
  //   py_RepetitionType.def(py::init<>());
  //   py_RepetitionType.def("__repr__", [](const RepetitionType& type) {
  //     std::string res = "qlib object RepetitionType: ";
  //     switch (type) {
  //       case RepetitionType::None:
  //         res += "None";
  //         break;
  //       case RepetitionType::Rectangular:
  //         res += "Rectangular";
  //         break;
  //       case RepetitionType::Regular:
  //         res += "Regular";
  //         break;
  //       case RepetitionType::Explicit:
  //         res += "Explicit";
  //         break;
  //       case RepetitionType::ExplicitX:
  //         res += "ExplicitX";
  //         break;
  //       case RepetitionType::ExplicitY:
  //         res += "ExplicitY";
  //         break;
  //     }
  //     return res;
  //   });
  //   py_RepetitionType.value("None", RepetitionType::None);
  //   py_RepetitionType.value("Rectangular", RepetitionType::Rectangular);
  //   py_RepetitionType.value("Regular", RepetitionType::Regular);
  //   py_RepetitionType.value("Explicit", RepetitionType::Explicit);
  //   py_RepetitionType.value("ExplicitX", RepetitionType::ExplicitX);
  //   py_RepetitionType.value("ExplicitY", RepetitionType::ExplicitY);
  //   py_RepetitionType.export_values();

  //   py::class_<Repetition> py_Repetition(m, "Repetition");
  //   py_Repetition.def(py::init<const RepetitionType&>());
  //   py_Repetition.def("__repr__", [](const Repetition& repet) {
  //     std::string res = "qlib object Repetition: \n";
  //     switch (repet.type) {
  //       case RepetitionType::None:
  //         res += "Type: None";
  //         break;
  //       case RepetitionType::Rectangular:
  //         res += "Type: Rectangular";
  //         res += "\n columns: " + std::to_string(repet.columns);
  //         res += "\n rows: " + std::to_string(repet.rows);
  //         res += "\n spacing: [" + std::to_string(repet.spacing.x) + "," + std::to_string(repet.spacing.y) + "]";
  //         break;
  //       case RepetitionType::Regular:
  //         res += "Type: Regular";
  //         res += "Type: Rectangular";
  //         res += "\n columns: " + std::to_string(repet.columns);
  //         res += "\n rows: " + std::to_string(repet.rows);
  //         res += "\n v1: [" + std::to_string(repet.v1.x) + "," + std::to_string(repet.v1.y) + "]";
  //         res += "\n v2: [" + std::to_string(repet.v2.x) + "," + std::to_string(repet.v2.y) + "]";
  //         break;
  //       case RepetitionType::Explicit:
  //         res += "Type: Explicit";
  //         break;
  //       case RepetitionType::ExplicitX:
  //         res += "Type: ExplicitX";
  //         break;
  //       case RepetitionType::ExplicitY:
  //         res += "Type: ExplicitY";
  //         break;
  //     }
  //     return res;
  //   });

  //   py_Repetition.def_readwrite("type", &Repetition::type);
  //   py_Repetition.def_readwrite("columns", &Repetition::columns);
  //   py_Repetition.def_readwrite("rows", &Repetition::rows);
  //   py_Repetition.def_readwrite("spacing", &Repetition::spacing);
  //   py_Repetition.def_readwrite("v1", &Repetition::v1);
  //   py_Repetition.def_readwrite("v2", &Repetition::v2);
  //   py_Repetition.def_readwrite("offsets", &Repetition::offsets);
  //   py_Repetition.def_readwrite("coords", &Repetition::coords);
  // }

  // // Property
  // {
  //   // PropertyType
  //   py::enum_<PropertyType> py_PropertyType(m, "PropertyType");
  //   py_PropertyType.def(py::init<>());
  //   py_PropertyType.def("__repr__", [](const PropertyType& type) {
  //     std::string res = "qlib object PropertyType: ";
  //     switch (type) {
  //       case PropertyType::UnsignedInteger:
  //         res += "Unsigned Integer";
  //         break;
  //       case PropertyType::Integer:
  //         res += "Integer";
  //         break;
  //       case PropertyType::Real:
  //         res += "Real";
  //         break;
  //       case PropertyType::String:
  //         res += "String";
  //         break;
  //       case PropertyType::ReferenceNumber:
  //         res += "Reference Number";
  //         break;
  //     }
  //     return res;
  //   });
  //   py_PropertyType.value("UnsignedInteger", PropertyType::UnsignedInteger);
  //   py_PropertyType.value("Integer", PropertyType::Integer);
  //   py_PropertyType.value("Real", PropertyType::Real);
  //   py_PropertyType.value("String", PropertyType::String);
  //   py_PropertyType.value("ReferenceNumber", PropertyType::ReferenceNumber);
  //   py_PropertyType.export_values();

  //   // PropertyValue
  //   py::class_<PropertyValue, std::shared_ptr<PropertyValue>> py_PropertyValue(m, "PropertyValue");
  //   py_PropertyValue.def(py::init<>());
  //   DEF_STATS(PropertyValue, type);
  //   DEF_STATS(PropertyValue, unsigned_integer);
  //   DEF_STATS(PropertyValue, integer);
  //   DEF_STATS(PropertyValue, real);
  //   DEF_STATS(PropertyValue, reference_number);
  //   DEF_STATS(PropertyValue, string);

  //   // PropertyValueArray
  //   py::bind_vector<PropertyValueArray>(m, "PropertyValueArray");
  //   m.def("PrvArray_Size", &vector_size<PropertyValue>);
  //   m.def("PrvArray_Resize", &vector_resize<PropertyValue>);

  //   // Property
  //   py::class_<Property, std::shared_ptr<Property>> py_Property(m, "Property");
  //   py_Property.def(py::init<>());
  //   py_Property.def_static("create", py::overload_cast<>(&Property::create));

  //   DEF_STATS(Property, name);
  //   DEF_STATS(Property, values);

  //   // PropertyArray
  //   py::bind_vector<PropertyArray>(m, "PropertyArray");
  //   m.def("ProArray_Size", &vector_size<Property>);
  //   m.def("ProArray_Resize", &vector_resize<Property>);

  //   // 属性操作的公共方法
  //   m.def("set_property", py::overload_cast<PropertyArray&, std::string, uint64_t, bool>(&set_property));
  //   m.def("set_property", py::overload_cast<PropertyArray&, std::string, int64_t, bool>(&set_property));
  //   m.def("set_property", py::overload_cast<PropertyArray&, std::string, double, bool>(&set_property));
  //   m.def("set_property", py::overload_cast<PropertyArray&, std::string, std::string, bool>(&set_property));
  // }

  // // Vec2d
  // {
  //   py::class_<Vec2d> py_Vec2d(m, "Vec2d");

  //   py_Vec2d.def(py::init<double, double>());
  //   py_Vec2d.def_readwrite("x", &Vec2d::x);
  //   py_Vec2d.def_readwrite("y", &Vec2d::y);
  //   py_Vec2d.def("__repr__", [](const Vec2d& v) { return "qlib object Vec2d: [" + std::to_string(v.x) + "," + std::to_string(v.y) + "]"; });

  //   DEF_METHOD(Vec2d, inner);
  //   DEF_METHOD(Vec2d, length_sq);
  //   DEF_METHOD(Vec2d, length);
  //   DEF_METHOD(Vec2d, normalize);
  //   DEF_METHOD(Vec2d, cross);
  //   DEF_METHOD(Vec2d, angle);
  //   DEF_METHOD(Vec2d, angle_vec);
  //   DEF_METHOD(Vec2d, ortho);

  //   py_Vec2d.def("set", py::overload_cast<const Vec2d&>(&Vec2d::operator=));
  //   py_Vec2d.def(py::self == py::self);
  //   py_Vec2d.def(py::self != py::self);
  //   py_Vec2d.def(py::self < py::self);
  //   py_Vec2d.def(py::self > py::self);
  //   py_Vec2d.def(py::self <= py::self);
  //   py_Vec2d.def(py::self >= py::self);

  //   py_Vec2d.def(py::self + py::self);
  //   py_Vec2d.def(py::self + float());
  //   py_Vec2d.def(float() + py::self);

  //   py_Vec2d.def(py::self - py::self);
  //   py_Vec2d.def(py::self - float());

  //   py_Vec2d.def(py::self * py::self);
  //   py_Vec2d.def(py::self * float());
  //   py_Vec2d.def(float() * py::self);

  //   py_Vec2d.def(py::self / py::self);
  //   py_Vec2d.def(py::self / float());

  //   py_Vec2d.def(py::self += py::self);
  //   py_Vec2d.def(py::self += float());

  //   py_Vec2d.def(py::self -= py::self);
  //   py_Vec2d.def(py::self -= float());

  //   py_Vec2d.def(py::self *= py::self);
  //   py_Vec2d.def(py::self *= float());

  //   py_Vec2d.def(py::self /= py::self);
  //   py_Vec2d.def(py::self /= float());

  //   m.def("cplx_conj", &cplx_conj<double>);
  //   m.def("cplx_mul", &cplx_mul<double>);
  //   m.def("cplx_inv", &cplx_inv<double>);
  //   m.def("cplx_div", &cplx_div<double>);
  //   m.def("cplx_from_angle", &cplx_from_angle<double>);

  //   py::bind_vector<Vec2dArray>(m, "Vec2dArray");
  //   m.def("Vec2Array_Size", &vector_size<Vec2d>);
  //   m.def("Vec2Array_Resize", &vector_resize<Vec2d>);

  //   py::bind_vector<std::vector<double>>(m, "DArray");
  //   m.def("DouArray_Size", &vector_size<double>);
  //   m.def("DouArray_Resize", &vector_resize<double>);
  // }

  // // Error code
  // {
  //   py::enum_<ErrorCode> py_ErrorCode(m, "ErrorCode");
  //   py_ErrorCode.def(py::init<>());
  //   py_ErrorCode.def("__repr__", [](const ErrorCode& type) { std::string res = "qlib object ErrorCode: " + std::to_string((int)type); });
  //   py_ErrorCode.value("NoError", ErrorCode::NoError);
  //   py_ErrorCode.value("BooleanError", ErrorCode::BooleanError);
  //   py_ErrorCode.value("IntersectionNotFound", ErrorCode::IntersectionNotFound);
  //   py_ErrorCode.value("MissingReference", ErrorCode::MissingReference);
  //   py_ErrorCode.value("UnsupportedRecord", ErrorCode::UnsupportedRecord);
  //   py_ErrorCode.value("UnofficialSpecification", ErrorCode::UnofficialSpecification);
  //   py_ErrorCode.value("InvalidRepetitio", ErrorCode::InvalidRepetition);
  //   py_ErrorCode.value("Overflow", ErrorCode::Overflow);
  //   py_ErrorCode.value("ChecksumError", ErrorCode::ChecksumError);
  //   py_ErrorCode.value("OutputFileOpenError", ErrorCode::OutputFileOpenError);
  //   py_ErrorCode.value("InputFileOpenError", ErrorCode::InputFileOpenError);
  //   py_ErrorCode.value("InputFileError", ErrorCode::InputFileError);
  //   py_ErrorCode.value("FileError", ErrorCode::FileError);
  //   py_ErrorCode.value("InvalidFile", ErrorCode::InvalidFile);
  //   py_ErrorCode.value("InsufficientMemory", ErrorCode::InsufficientMemory);
  //   py_ErrorCode.value("ZlibError", ErrorCode::ZlibError);
  //   py_ErrorCode.export_values();
  // }
}